package net.qhzw.vip.qiyu.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.vip.qiyu.config.WxPayConfiguration;
import net.qhzw.vip.qiyu.constant.CacheConstants;
import net.qhzw.vip.qiyu.dto.DtsCarTransferPayDto;
import net.qhzw.vip.qiyu.entity.DtsCarRental;
import net.qhzw.vip.qiyu.entity.DtsCarTransfer;
import net.qhzw.vip.qiyu.entity.DtsCarTransferRefund;
import net.qhzw.vip.qiyu.entity.RepairMaint;
import net.qhzw.vip.qiyu.handler.ApiException;
import net.qhzw.vip.qiyu.model.DtsCarTransferForm;
import net.qhzw.vip.qiyu.model.DtsCarTransferVo;
import net.qhzw.vip.qiyu.result.JsonResult;
import net.qhzw.vip.qiyu.service.*;
import net.qhzw.vip.qiyu.util.RedisUtils;
import net.qhzw.vip.qiyu.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("dts/carTransfer")
@Api(tags = "换车申请管理")
@Slf4j
public class DtsCarTransferController {

    @Autowired
    private DtsCarTransferService dtsCarTransferService;

    @Autowired
    private PayService payService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private RepairMaintService repairMaintService;

    @Autowired
    private DtsCarRentalService dtsCarRentalService;

    @Autowired
    private DtsCarTransferRefundService carTransferRefundService;


    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("checked/{id}")
    public JsonResult checked(@PathVariable Long id) {
        int count = dtsCarTransferService.count(new LambdaQueryWrapper<DtsCarTransfer>()
                .eq(DtsCarTransfer::getCarRentalId, id)
                .eq(DtsCarTransfer::getStatus, 1));
        if (count > 0) {
            throw new ApiException("您目前有换车订单先结束订单后在申请!");
        }
        DtsCarRental carRental = dtsCarRentalService.getById(id);
        if (0 != carRental.getStopRep()){
            throw new ApiException("您已报停租车,请先回复后,在申请换车!");
        }
        return JsonResult.ok();
    }


    @ApiOperation(value = "换车维修支付")
    @PostMapping("pay")
    public JsonResult pay(@RequestBody DtsCarTransferPayDto payDto) {
        Long carRentalId = payDto.getCarRentalId();
        checkPay(carRentalId);
        DtsCarRental carRental = dtsCarRentalService.getById(carRentalId);
        Long shopId = SecurityUtils.getLoginUser().getShopId();
        BigDecimal totalPrice = new BigDecimal(0);
        if (!CollectionUtils.isEmpty(payDto.getMaintIds())) {
            List<RepairMaint> repairMaints = repairMaintService.listByIds(payDto.getMaintIds());
            if (!CollectionUtils.isEmpty(repairMaints)) {
                for (RepairMaint repairMaint : repairMaints) {
                    totalPrice = totalPrice.add(repairMaint.getPrice());
                }
            }
        }

        LambdaQueryWrapper<DtsCarTransfer> queryWrapper = new LambdaQueryWrapper<DtsCarTransfer>()
                .eq(DtsCarTransfer::getCarRentalId, carRentalId);
        int count = dtsCarTransferService.count(queryWrapper);
        DtsCarTransfer dtsCarTransfer = new DtsCarTransfer();
        dtsCarTransfer.setCarRentalId(payDto.getCarRentalId());
        dtsCarTransfer.setOthrFee(payDto.getOthrFee());
        dtsCarTransfer.setMaintFee(totalPrice);
        dtsCarTransfer.setFeeStatus("未付");
        dtsCarTransfer.setTransferOpinion("--");
        String payNo = IdWorker.getId() + "";
        dtsCarTransfer.setPayNo(payNo);
        Long carTransferId = null;
        if (count > 0) {
            carTransferId = dtsCarTransferService.getOne(queryWrapper).getId();
            dtsCarTransferService.update(dtsCarTransfer, queryWrapper);
        } else {
            carTransferId = IdWorker.getId();
            dtsCarTransfer.setId(carTransferId);
            dtsCarTransferService.save(dtsCarTransfer);
        }
        payDto.setTotalFee(totalPrice.add(payDto.getOthrFee()));
        payDto.setPayNo(payNo);
        payDto.setCarTransferId(carTransferId);
        String payCode = "";
        if (payDto.getOthrFee().doubleValue() > 0 || payDto.getTotalFee().doubleValue() > 0) {
            LambdaQueryWrapper<DtsCarTransferRefund> queryTransferRefund = new LambdaQueryWrapper<DtsCarTransferRefund>()
                    .eq(DtsCarTransferRefund::getCarTransferId, carTransferId);
            int countTransferRefund = carTransferRefundService.count(queryTransferRefund);
            //调用微信支付
            payCode = payService.carTransPay(carRental.getShopId(), payDto);
            DtsCarTransferRefund transferRefund = new DtsCarTransferRefund();
            transferRefund.setCarTransferId(carTransferId);
            transferRefund.setFee(payDto.getTotalFee().doubleValue());
            transferRefund.setRefundNo(payDto.getPayNo());
            if (countTransferRefund > 0) {
                carTransferRefundService.update(transferRefund, queryTransferRefund);
            } else {
                carTransferRefundService.save(transferRefund);
            }
        }
        return JsonResult.ok(payCode);
    }

    private void checkPay(Long carRentalId) {
        Integer isPay = dtsCarTransferService.checkPay(carRentalId);
        if (isPay != null && 1 == isPay) {
            throw new ApiException("您已经支付了,无需重新支付");
        }
    }

    @ApiOperation(value = "换车维修支付回调")
    @PostMapping("/pay/notify")
    @Transactional
    public JsonResult payNotify(@RequestBody String xmlData) {
        WxPayOrderNotifyResult rs = WxPayOrderNotifyResult.fromXML(xmlData);
        String SubMchId = rs.getSubMchId();
        String appId = rs.getAppid();
        String outTradeNo = rs.getOutTradeNo();
        String transactionId = rs.getTransactionId();
        WxPayConfig wxPayConfig = new WxPayConfig();
        wxPayConfig.setSubMchId(SubMchId);
        WxPayService wxPayService = WxPayConfiguration.getPayService(wxPayConfig);
        String orderCache = (String) redisTemplate.boundListOps(CacheConstants.CAR_TRANSFER_ORDER_CACHE + ":" + outTradeNo).rightPop();
        if (orderCache != null) {
            DtsCarTransfer dtsCarTransfer = dtsCarTransferService.getById(orderCache);
            if (dtsCarTransfer != null || dtsCarTransfer.getIsPay() != 1) {
                //修改换车订单
                dtsCarTransfer.setBizPayNo(transactionId);
                dtsCarTransfer.setFeeStatus("已付");
                dtsCarTransfer.setPayTime(new Date());
                dtsCarTransfer.setIsPay((byte) 1);
                dtsCarTransferService.updateById(dtsCarTransfer);
            }
            //记录换车支付
            DtsCarTransferRefund transferRefund = new DtsCarTransferRefund();
            transferRefund.setTransactionId(transactionId);
            transferRefund.setCarTransferId(dtsCarTransfer.getId());
            transferRefund.setIsRefund((byte) 1);
            transferRefund.setRefundTime(new Date());
            transferRefund.setAppId(appId);
            carTransferRefundService.update(transferRefund, new LambdaQueryWrapper<DtsCarTransferRefund>()
                    .eq(DtsCarTransferRefund::getCarTransferId, orderCache));
        }

        return JsonResult.ok();
    }


    @ApiOperation(value = "查询换车申请列表")
    @GetMapping
    public JsonResult findByPage(Page<DtsCarTransfer> page, String idCard, String mobile, String realName) {
        Long shopId = SecurityUtils.getLoginUser().getShopId();
        Map<String, Object> result = dtsCarTransferService.findByPage(page, idCard, mobile, realName, shopId);
        return JsonResult.ok(result);
    }

    @ApiOperation(value = "换车申请提交")
    @PostMapping("carChgApp")
    public JsonResult carChgApp(@RequestBody DtsCarTransferForm form, HttpServletRequest request) {
        boolean isOK = dtsCarTransferService.carChgApp(form, request);
        if (isOK) {
            return JsonResult.ok();
        }
        return JsonResult.fail();
    }

    @ApiOperation(value = "换车审核")
    @PostMapping("changeReview")
    public JsonResult changeReview(@RequestBody Map<String, String> param, HttpServletRequest request) {
        Long shopId = SecurityUtils.getLoginUser().getShopId();
        if (shopId == 1) {
            throw new ApiException("您是超级管理员, 不能审核该订单!");
        }
        Long id = Long.valueOf(param.get("id"));
        Byte status = Byte.valueOf(param.get("status"));
        String transferOpinion = param.get("transferOpinion");
        Long communityId = Long.valueOf(param.get("communityId"));
        boolean isOK = dtsCarTransferService.changeReview(id, status, transferOpinion, communityId, request);
        if (isOK) {
            return JsonResult.ok();
        }
        return JsonResult.fail();
    }


    @ApiOperation(value = "换车退款回调")
    @RequestMapping("refund/notify")
    public JsonResult refundNotify(@RequestBody String xmlData) {
        log.info("【退车退款回调】： {}", xmlData);
        WxPayOrderNotifyResult rs = WxPayOrderNotifyResult.fromXML(xmlData);
        String appId = rs.getAppid();
        String SubMchId = rs.getSubMchId();
        WxPayConfig wxPayConfig = new WxPayConfig();
        wxPayConfig.setAppId(appId);
        wxPayConfig.setSubMchId(SubMchId);
        WxPayService wxPayService = WxPayConfiguration.getPayService(wxPayConfig);
        try {
            WxPayRefundNotifyResult wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);
            log.info("处理退款回调成功: {}", JSON.toJSONString(wxPayRefundNotifyResult));
            if (wxPayRefundNotifyResult.getReturnCode().equals("SUCCESS")) {
                WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();
                String outRefundNo = reqInfo.getOutRefundNo();
                LambdaQueryWrapper<DtsCarTransferRefund> query = new LambdaQueryWrapper<DtsCarTransferRefund>()
                        .eq(DtsCarTransferRefund::getRefundNo, outRefundNo);
                DtsCarTransferRefund transferRefund = carTransferRefundService.getOne(query);
                if (transferRefund != null) {
                    transferRefund.setIsRefund((byte) 1);
                    transferRefund.setRefundTime(new Date());
                    carTransferRefundService.update(transferRefund, query);
                }
            }
            return JsonResult.ok(wxPayRefundNotifyResult);
        } catch (WxPayException e) {
            e.printStackTrace();
            return JsonResult.fail(e.getReturnMsg() + "" + e.getCustomErrorMsg() + "" + e.getErrCodeDes());
        }
    }

   /* @ApiOperation(value = "换车退款回调")
    @RequestMapping("refund/notify")
    public JsonResult refundNotify(@RequestBody String xmlData) {
        log.info("【换车退款回调】： {}", xmlData);
        WxPayRefundNotifyResult wxPayRefundNotifyResult = null;
        try {
            //wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);
            wxPayRefundNotifyResult = null;
            if (wxPayRefundNotifyResult.getReturnCode().equals("SUCCESS")) {
                WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();
                String outRefundNo = reqInfo.getOutRefundNo();
                LambdaQueryWrapper<DtsCarTransferRefund> query = new LambdaQueryWrapper<DtsCarTransferRefund>()
                        .eq(DtsCarTransferRefund::getRefundNo, outRefundNo);
                DtsCarTransferRefund transferRefund = carTransferRefundService.getOne(query);
                if (transferRefund != null) {
                    transferRefund.setIsRefund((byte) 1);
                    transferRefund.setRefundTime(new Date());
                    carTransferRefundService.update(transferRefund, query);
                }
            }
        } catch (Exception e) {
            log.error("退款失败，失败信息:{}", e);
        }
        return JsonResult.ok();
    }*/

    @ApiOperation(value = "查询当前骑手换车订单")
    @GetMapping("getCarTransferByUser")
    public JsonResult getCarTransferByUser() {
        DtsCarTransferVo dtsCarTransferVo = dtsCarTransferService.getCarTransferByUser();
        return JsonResult.ok(dtsCarTransferVo);
    }

    @ApiOperation(value = "骑手确认换车费用")
    @PostMapping("exchangeFee")
    public JsonResult exchangeFee(@RequestBody Map<String, String> param) {
        Long id = Long.valueOf(param.get("id"));
        Byte userConfirm = Byte.valueOf(param.get("userConfirm"));
        String userOpinion = param.get("userOpinion");
        boolean isOK = dtsCarTransferService.exchangeFee(id, userConfirm, userOpinion);
        if (isOK) {
            return JsonResult.ok();
        }
        return JsonResult.fail();
    }

}
